#ifndef MODBUS_FACTORY_H
#define MODBUS_FACTORY_H

#include <QtCore>

//前置声明
class CRTDB;
class CBattStack;
class CBattBank;
typedef struct _SMdobusTcpReq SMdobusTcpReq;
typedef struct _SAlarmParam SAlarmParam;
class CBankAlarm;
class CIOModule;
class CPcsData;

class CModbusFactory
{
public:
	CModbusFactory();
	~CModbusFactory();

    void SetRtdb(CRTDB* pRtdb);
    void SetProjectMode(int iProjectMode);

public:
	// BA
	int prepareDatagram(int iIndexStep, char* pSendDataBuf, uchar uaAddr);
	int analyDatagram(int iIndexStep, char* pRecDataBuf, int iLen, CBattBank* pCurBattData);
	int analyComInputRegDatagram(char* pRecDataBuf, int iLen, quint16* pComInputRegData);
	int analyStackDatagram(char* pRecDataBuf, int iLen, CBattStack* pStack);
//	int prepareSetHoldDatagram(int iSetHoldRegStep, CBattStack* pStack, CBattBank* pBattBank, SAlarmParam* pAlarmParam, char* pSendDataBuf);// Hold Register
//	int analySetHoldReturnDatagram(char* pRecDataBuf, int iLen);
	int analyStackHoldDatagram(char* pRecDataBuf, int iLen, CBattStack* pStack);
//	int analyBankHoldDatagram(char* pRecDataBuf, int iLen, CBattBank* pBattBank, SAlarmParam* pAlarmParam);

	// Data tran
	int analyReqDatagram(char* pDataBuf, int iLen, SMdobusTcpReq& req);
	int prepareBattDatagram(char* pDataBuf, SMdobusTcpReq* pReq, CBattBank* pBattBank);
	int prepareAlarmCacheDatagram(char* pDataBuf, SMdobusTcpReq* pReq, CBattBank* pBattBank, CBankAlarm* pBankAlarm);
	int prepareStackDatagram(char* pDataBuf, SMdobusTcpReq* pReq, CBattStack* pBattStack);
	int prepareEnvDatagram(char* pDataBuf, SMdobusTcpReq* pReq, CBattStack* pBattStack, int iModbusAddress);
	int prepareBankAlarmDatagram(char* pDataBuf, SMdobusTcpReq* pReq, SAlarmParam* pAlarmParam, CBattBank* pBattBank, CBattStack* pBattStack);
	int prepareExcepDatagram(char* pDataBuf, SMdobusTcpReq* pReq, uchar uaExcepCode);
	int prepareBAComInputRegDatagram(char* pDataBuf, SMdobusTcpReq* pReq, quint16* pComInputRegData);
	int prepareBAComHoldRegDatagram(char* pDataBuf, SMdobusTcpReq* pReq, quint16* pComHoldRegData);

    //获取电池堆的相关变量的quint16/float值
	int getRegValStack(quint16 usRegAddr, CBattStack* pBattStack, quint16& usVal, float& fVal);
    //获取电池堆的环境变量的quint16/float值
    int getRegValEnv(int iModbusAddress, quint16 usRegAddr, CBattStack* pBattStack, quint16& usVal, float& fVal);
    int getRegValAc(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValTh(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValWater(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValFire(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValLc(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValPcs(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValMeter(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValEc(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValDoor(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValGas(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValDcdc(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValCp(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValDh(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValFan(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValSts(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValPress(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValLevel(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValPv(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValUps(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    int getRegValLed(int iDevIndex, quint16 usRegAddr, quint16& usVal, float& fVal);
    //获取电池组的相关变量的quint16/float/quint32值
    int getRegValBank(quint16 usRegAddr, CBattBank* pBattBank, quint16& usVal, float& fVal, quint32& uiVal);
    //获取电池组的相关变量的离散值
	int getRegValBankDis(quint16 usRegAddr, CBattBank* pBattBank);
    //获取电池堆的告警变量的离散值
	int getRegValStackDis(quint16 usRegAddr, CBattStack* pBattStack);
    //获取电池堆的环境变量的离散值
	int getRegValEnvDis(int iModbusAddress, quint16 usRegAddr, CBattStack* pBattStack);

	int addParam2Buffer(char* pData, quint32 uiParamVal);
	int addParam2Buffer(char* pData, quint16 uiParamVal);
	int addParam2Buffer(char* pData, float fParamVal);

	// RTU
	int addModbusCRC2Buffer(char *pData, int iLen);
	int analyDatagramRtuPCS(char *pData, int iLen);

private:
	int getParamFromBuffer(char* pData, quint16& uiParamVal);
	int getParamFromBuffer(char* pData, quint32& uiParamVal);
	int getParamFromBuffer(char* pData, float& fParamVal);

	int formDatagram(quint16 usEvent, uchar uaAddr, uchar uaFuncCode, quint16 usStartReg, quint16 usRegNum, char* pSendDataBuf);
	int formHoldRegDatagram(quint16 usEvent, uchar uaAddr, quint16 usStartReg, quint16 usRegNum, char* pSendDataBuf, float* pFVal);

	void addRegVal2BufferBankDis(char* pData, quint16 usRegAddr, CBattBank* pBattBank);
	quint16 addRegVal2BufferBank(char* pData, quint16 usRegAddr, CBattBank* pBattBank);
	quint16 addRegVal2BufferStack(char* pData, quint16 usRegAddr, CBattStack* pBattStack);
    //增加环境变量数据到发送缓冲区
    //返回处理的寄存器个数(一个寄存器两个字节)
    //quint16类型返回1，float类型返回2
    quint16 addRegVal2BufferEnv(char* pData, quint16 usRegAddr, CBattStack* pBattStack, int iModbusAddress);

    int setEnvAcValue(int iDevIndex, quint16 usRegAddr, quint16 usVal);
    int setEnvLcValue(int iDevIndex, quint16 usRegAddr, quint16 usVal);
    int setEnvPcsValue(int iDevIndex, quint16 usRegAddr, quint16 usVal);

	int setAlarmHoldRegVal(quint16 usRegAddr, quint16 usVal, SAlarmParam* pAlarmParam, CBattBank* pBattBank, CBattStack* pBattStack);
	int setStackHoldRegVal(quint16 usRegAddr, quint16 usVal, CBattStack* pBattStack);
	int addHoldRegVal2BufferAlarm(char* pData, quint16 usRegAddr, SAlarmParam* pAlarmParam, CBattBank* pBattBank);
	int addHoldRegVal2BufferStack(char* pData, quint16 usRegAddr, CBattStack* pBattStack);

	quint16 Modbus_CRC16(char *pData, quint16 usLen);

private:
    CRTDB*              m_pRtdb;
    // #项目模式,默认为0
    // #0,通用项目
    // #1,富仁项目--给第三方EMS提供液冷数据,动环测量(Modbus地址从101,输入寄存器,功能码0x04,共13个UINT16数据,寄存器地址为201~213)
    // #2,海得项目
    // #--提供电表,动环测量(Modbus地址从101,输入寄存器,功能码0x04,共32个FLOAT数据,寄存器地址为201~264)
    // #--提供液冷,动环测量(Modbus地址从101,输入寄存器,功能码0x04,共4个UINT16数据,寄存器地址为301~304)
    // #--提供液冷,动环测量(Modbus地址从101,输入寄存器,功能码0x04,共8个FLOAT数据,寄存器地址为311~326)
    // #--提供PCS的UNIT16数据(Modbus地址从200,输入寄存器,功能码0x04,共9个UINT16数据,寄存器地址为0,2~9,没有1)
    // #--提供PCS的FLOAT数据(Modbus地址从200,输入寄存器,功能码0x04,共25个FLOAT数据,寄存器地址为51~99)
    // #--提供PCS的BIT数据(Modbus地址从200,离散寄存器,功能码0x02,共4个数据,寄存器地址为1~4)
    int                 m_iProjectMode; //项目模式
};

#endif // MODBUS_FACTORY_H
